﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Web.UI.WebControls;
using Foothill.Common;
using Foothill.Common.Logging;
using Foothill.IoC;
using Foothill.Model;
using Foothill.Service.AdService;
using Foothill.Service.Security;
using Foothill.Service.SystemMessage;
using Foothill.Service.UserAccount;
using Foothill.Service.Email;

namespace Foothill.Web.UserProfile
{
    public partial class User : FoothillBasePage
    {
        private UserAccountDto _userAccount;
        private IUserAccountService _userAccountService;
        private IAdService _adService;
        private ISystemMessageService _systemMessageService;
        private IEmailService _emailService;

        public int PostsByUserTotalCount
        {
            set
            {
                ViewState["PostsByUserTotalCount"] = value;
            }

            get
            {
                return ConvertToInt(ViewState["PostsByUserTotalCount"]);
            }
        }

        public int SavedPostsTotalCount
        {
            set
            {
                ViewState["SavedPostsTotalCount"] = value;
            }

            get
            {
                return ConvertToInt(ViewState["SavedPostsTotalCount"]);
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            _userAccountService = IocContainer.GetInstance<IUserAccountService>();
            _adService = IocContainer.GetInstance<IAdService>();
            _systemMessageService = IocContainer.GetInstance<ISystemMessageService>();
            _emailService = IocContainer.GetInstance<IEmailService>();
            
            if (!User.Identity.IsAuthenticated)
            {
                Response.Redirect("~/Login/Login.aspx");
            }
            else
            {
                PopulatePage();
                lblChangePasswordMessage.Visible = false;
            }
        }

        private void PopulatePage()
        {
            _userAccount = _userAccountService.GetUserAccountDetailsByUserName(User.Identity.Name);

            if (_userAccount == null || _userAccount.UserAccountId < 0 || _userAccount.AccountStateId != (int)UserAccountState.Active)
            {
                // todo: display error message
                hlkEdit.Visible = false;
            }
            else
            {
                PopulateUserInformation();
                PopulateMyPosts();
                PopulateMySavedPosts();
            }
        }

        private void PopulateUserInformation()
        {
            lblUserName.Text = _userAccount.Username;
            lblEmailValue.Text = _userAccount.Email;
            lblPhoneNumberValue.Text = _userAccount.ContactPhone;
            lblContactNameValue.Text = _userAccount.ContactName;
            lblMemberSinceValue.Text = _userAccount.DateActivated.ToString("D");

            tbxIntro.Text = _userAccount.Intro;

            if (string.IsNullOrWhiteSpace(_userAccount.UserProfilePhotoPath))
            {
                imgUserProfile.ImageUrl = GlobalSettings.DefaultProfilePhoto;
            }
            else
            {
                imgUserProfile.ImageUrl = _userAccountService.GetProfilePhotoFileUrl(_userAccount.UserProfilePhotoPath);
            }

            if (string.IsNullOrWhiteSpace(_userAccount.UserLogoFilePath))
            {
                imgLogo.ImageUrl = GlobalSettings.DefaultLogoPhoto;
            }
            else
            {
                imgLogo.ImageUrl = _userAccountService.GetLogoFileUrl(_userAccount.UserLogoFilePath);
            }
        }

        private void PopulateMyPosts()
        {
            int totalCount = 0;
            IList<ForSaleAd> onePageResult = _adService.GetPostsByUser(_userAccount.UserAccountId, 1, out totalCount);

            PostsByUserTotalCount = totalCount;
            gvwMyPosts.DataSource = onePageResult;
            gvwMyPosts.DataBind();

            MyPostsPager.RecordCount = totalCount;
            MyPostsPager.PageSize = GlobalSettings.PostsByUserPageSize;
        }

        private void PopulateMySavedPosts()
        {
            int totalCount = 0;
            IList<ForSaleAd> posts = _adService.GetUserSavedPosts(_userAccount.UserAccountId, 1, out totalCount);

            SavedPostsTotalCount = totalCount;
            gvwMySavedPosts.DataSource = posts;
            gvwMySavedPosts.DataBind();

            SavedPostsPager.RecordCount = totalCount;
            SavedPostsPager.PageSize = GlobalSettings.UserSavedListPageSize;
        }

        // handles bind the ad instance to each row
        protected void gvwMyPostsRowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                ForSaleAd post = e.Row.DataItem as ForSaleAd;

                SetupAdHyperlink(e.Row, post);

                DisplayAdSummary(e.Row, post);

                DisplayProfilePicture(e.Row, post);

                DisplayMileageAndPrice(e.Row, post);

                DisplayCityAndPostDate(e.Row, post);
            }
        }

        private void SetupAdHyperlink(WebControl row, ForSaleAd post)
        {
            string url = string.Format("~/ForSaleAdDetail/ForSaleAdDetail.aspx?{0}={1}", GlobalQueryString.AdDetailsQsName, post.AdId);
            HyperLink link = row.FindControl("hlkAdTitle") as HyperLink;
            link.NavigateUrl = url;

            link = row.FindControl("hlkProfilePic") as HyperLink;
            link.NavigateUrl = url;

            link = row.FindControl("hlkEditPost") as HyperLink;
            int maskedAdId = SecurityUtility.MaskEditPostId(post.AdId);
            link.NavigateUrl = _emailService.BuildEditPostLink(maskedAdId, post.EditKey);
        }

        // Make, Model, and year
        private void DisplayAdSummary(WebControl row, ForSaleAd post)
        {
            Label lblVehicleType = row.FindControl("lblVehicleType") as Label;
            lblVehicleType.Text = post.GetVehicleTypeString();
        }

        private void DisplayProfilePicture(WebControl row, ForSaleAd post)
        {
            Image imgProfile = row.FindControl("imgProfile") as Image;

            if (imgProfile != null)
            {
                if (!string.IsNullOrEmpty(post.ProfilePhotoPath)) // if there is no profile photo, the ProfilePhotoPath will be empty
                {
                    string path = Path.Combine(GlobalSettings.ThumbnailFolder, Path.GetFileName(post.ProfilePhotoPath));

                    if (File.Exists(Server.MapPath(path)))
                    {
                        imgProfile.ImageUrl = path;
                        return;
                    }
                }

                // display "Photo Not Available" 
                imgProfile.ImageUrl = GlobalSettings.PhotoNotAvailablePath;
            }
        }

        private void DisplayMileageAndPrice(WebControl row, ForSaleAd post)
        {
            Label lblPrice = row.FindControl("lblPrice") as Label;
            lblPrice.Text = string.Format("${0}", post.Price.ToString());
        }

        private void DisplayCityAndPostDate(WebControl row, ForSaleAd post)
        {
            Label lblCity = row.FindControl("lblCity") as Label;
            lblCity.Text = post.CityName;

            Label lblPostDate = row.FindControl("lblPostDate") as Label;
            lblPostDate.Text = post.TimePosted.Date.ToShortDateString();
        }

        protected void gvwMySavedPostsRowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                ForSaleAd post = e.Row.DataItem as ForSaleAd;
                if (post != null)
                {
                    string url = string.Format("~/ForSaleAdDetail/ForSaleAdDetail.aspx?{0}={1}", GlobalQueryString.AdDetailsQsName, post.AdId);
                    HyperLink link = e.Row.FindControl("hlkAdTitle") as HyperLink;
                    link.NavigateUrl = url;

                    link = e.Row.FindControl("hlkProfilePic") as HyperLink;
                    link.NavigateUrl = url;

                    DisplayAdSummary(e.Row, post);

                    DisplayProfilePicture(e.Row, post);

                    DisplayMileageAndPrice(e.Row, post);

                    DisplayCityAndPostDate(e.Row, post);
                }
            }
        }

        protected void RemoveFromSavedClick(object sender, EventArgs e)
        {
            LinkButton savePostBtn = sender as LinkButton;

            if (savePostBtn != null)
            {
                GridViewRow row = savePostBtn.NamingContainer as GridViewRow;
                int postId = (int)gvwMySavedPosts.DataKeys[row.RowIndex].Value;

                _adService.RemovePostFromSavedList(_userAccount.UserAccountId, postId);
                PopulateMySavedPosts();
            }
        }

        protected void btnChangePasswordClick(object sender, EventArgs e)
        {
            ISecurityService _securityService = IocContainer.GetInstance<ISecurityService>();
                
            IList<ChangePasswordFields> fieldsToHighlight = new List<ChangePasswordFields>();
            string errorMessage;

            try
            {
                if (!_userAccountService.ChangePassword(_securityService.GetLoginUserDetails(), txtCurrentPassword.Text.Trim(),
                    txtNewPassword.Text.Trim(), txtConfirmPassword.Text.Trim(), fieldsToHighlight, out errorMessage))
                {
                    // display error message
                    DisplayChangePasswordError(errorMessage);
                }
                else
                {
                    lblChangePasswordMessage.Visible = true;
                    lblChangePasswordMessage.Text = _systemMessageService.GetSystemMessage(SystemMessageCategory.Security, SecurityMessageCode.ChangePassword_Succeed);
                    lblChangePasswordMessage.CssClass = "changepwd-succeed";
                }
            }
            catch (Exception ex)
            {
                Log.Error(FoothillModule.View, "Unexpected error in change password", ex);
                DisplayChangePasswordError(_systemMessageService.GetSystemMessage(SystemMessageCategory.Security, SecurityMessageCode.ChangePassword_FailedUnexpectedError));
            }      
        }

        protected void MyPostsPagerPageChanged(object src, EventArgs e)
        {
            int totalCount = 0;
            IList<ForSaleAd> onePageResult = _adService.GetPostsByUser(_userAccount.UserAccountId, MyPostsPager.CurrentPageIndex, out totalCount);

            gvwMyPosts.DataSource = onePageResult;
            gvwMyPosts.DataBind();
        }

        protected void SavedPostsPagerPageChanged(object src, EventArgs e)
        {
            int totalCount = 0;
            IList<ForSaleAd> onePageResult = _adService.GetUserSavedPosts(_userAccount.UserAccountId, SavedPostsPager.CurrentPageIndex, out totalCount);

            gvwMySavedPosts.DataSource = onePageResult;
            gvwMySavedPosts.DataBind();
        }

        private void DisplayChangePasswordError(string error)
        {
            lblChangePasswordMessage.Visible = true;
            lblChangePasswordMessage.Text = error;
            lblChangePasswordMessage.CssClass = "changepwd-error";
        }
    }
}